package com.yc.mybatis;

import com.yc.mybatis.bean.Movie;
import com.yc.mybatis.bean.Plan;
import com.yc.mybatis.bean.User;
import com.yc.mybatis.mapper.DemoMapper;
import com.yc.mybatis.mapper.MovieDao;
import com.yc.mybatis.mapper.PlanMapper;
import com.yc.mybatis.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MybatisTester {

    @Test
    public void test() throws IOException {
        String resource = "mybatis.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //创建会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //执行语句
        List<Map> list = sqlSession.selectList(
                "com.yc.mybatis.mapper.DemoMapper.selectUser");
        //打印结果
        list.forEach(System.out::println);
        System.out.println("list.get(0).get(\"name\") = " + list.get(0).get("name"));

        /////////////////
        DemoMapper mapper = sqlSession.getMapper(DemoMapper.class);
        List<User> users = mapper.selectUser1();
        users.forEach(System.out::println);
        System.out.println("users.get(0).getName() = " + users.get(0).getName());

        sqlSession.close();
    }


    SqlSession sqlSession;
    SqlSession sqlSession1;

    //在测试方法执行前执行的方法
    @Before
    public void before() throws IOException {
        String resource = "mybatis.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //创建会话
        sqlSession = sqlSessionFactory.openSession();
    }

    @After
    //在执行方法之后执行的方法
    public void after() {
        sqlSession.close();
    }

    @Test
    public void test1() {
        DemoMapper mapper = sqlSession.getMapper(DemoMapper.class);
        User user = mapper.selectById(1);
        Assert.assertEquals("张三", user.getName());

        // MyBatis默认自动回滚

        try{
            User newUser = new User();
            newUser.setId(3);
            newUser.setName("王五");
            newUser.setPwd("123");
            newUser.setBirthday(new Date(System.currentTimeMillis()));
            newUser.setEmail("");
            mapper.insert(newUser);
            user = mapper.selectById(3);
            Assert.assertEquals("王五", user.getName());
            //如果正常执行完成 则提交
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //如果执行出现异常 则回滚
            sqlSession.rollback();
        } finally {
            //不管正常还是异常都要关闭会话
            sqlSession.close();
        }

    }

    @Test
    public void test2() {
        DemoMapper mapper = sqlSession.getMapper(DemoMapper.class);
        try {
            User user = new User();
            user.setId(4);
            user.setName("赵六");
            mapper.insert(user);
            User dbUser = mapper.selectById(4);
            Assert.assertEquals("赵六", dbUser.getName());

            dbUser.setName("钱七");
            mapper.updateById(dbUser);
            dbUser = mapper.selectById(4);
            Assert.assertEquals("钱七", dbUser.getName());

            int i = mapper.deleteById(4);
            Assert.assertEquals(1, i);
            dbUser = mapper.selectById(4);
            Assert.assertNull(dbUser);
            sqlSession.commit();
        } catch (Exception e) {
            sqlSession.rollback();
        } finally {
            sqlSession.close();
        }
    }

    @Test
    public void test3() {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.selectForLogin("张三", "123");
    }

    @Test
    public void test4() {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.selectForLogin1("张三");

        Map<String, Object> params = new HashMap<>();
        params.put("name", "李四");
        params.put("pwd", "123");
        mapper.selectForLogin2(params);
    }

    @Test
    public void test5() {
        MovieDao mapper = sqlSession.getMapper(MovieDao.class);
        List<Movie> list = mapper.selectLikeName("是");

        list.forEach(System.out::println);
    }

    @Test
    public void test6() {
        PlanMapper planMapper = sqlSession.getMapper(PlanMapper.class);
        MovieDao movieDao = sqlSession.getMapper(MovieDao.class);

        Plan plan = planMapper.selectById(1);
        Movie movie = movieDao.selectById(plan.getMid());

        System.out.println("plan = " + plan);
        System.out.println("movie = " + movie);
    }

    @Test
    public void test7() {
        PlanMapper planMapper = sqlSession.getMapper(PlanMapper.class);
        //一对一关联查询
        Plan plan = planMapper.selectById1(1);
        //默认以积极加载方式完成
        System.out.println("plan.getId() = " + plan.getId());
        System.out.println("plan.getPlayTime() = " + plan.getPlayTime());
        System.out.println("plan.getMid() = " + plan.getMid());
        // 使用fetch="lazy" 开启延迟加载（惰性加载）
        System.out.println("plan.getMovie().getName() = " + plan.getMovie().getName());
        System.out.println("plan.getMovie().getLength() = " + plan.getMovie().getLength());
        System.out.println("plan.getMovie().getType() = " + plan.getMovie().getType());
//        Movie movie = plan.getMovie();
//        System.out.println("plan = " + plan);
//        System.out.println("movie = " + movie);
    }

    @Test
    public void test8() {
        PlanMapper planMapper = sqlSession.getMapper(PlanMapper.class);
        //一对一关联查询
        Plan plan = planMapper.selectById2(1);
        System.out.println("plan.getId() = " + plan.getId());
        System.out.println("plan.getPlayTime() = " + plan.getPlayTime());
        System.out.println("plan.getMid() = " + plan.getMid());
        System.out.println("plan.getMovie().getName() = " + plan.getMovie().getName());
        System.out.println("plan.getMovie().getLength() = " + plan.getMovie().getLength());
        System.out.println("plan.getMovie().getType() = " + plan.getMovie().getType());
    }

    @Test
    public void test9() {
        PlanMapper planMapper = sqlSession.getMapper(PlanMapper.class);
        //一对一关联查询
        Plan plan = planMapper.selectById3(1);
        System.out.println("plan.getId() = " + plan.getId());
        System.out.println("plan.getPlayTime() = " + plan.getPlayTime());
        System.out.println("plan.getMid() = " + plan.getMid());
        System.out.println("plan.getMovie().getName() = " + plan.getMovie().getName());
        System.out.println("plan.getMovie().getLength() = " + plan.getMovie().getLength());
        System.out.println("plan.getMovie().getType() = " + plan.getMovie().getType());
    }

    // 一对多关联查询
    @Test
    public void test10() {
        MovieDao movieDao = sqlSession.getMapper(MovieDao.class);
        Movie movie = movieDao.selectById(1);
        List<Plan> plans = movie.getPlans();
        plans.forEach(System.out::println);
    }

}
